using System.Net.Sockets;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

namespace WpfApp_ChenxiConsole.UDP
{
    /// <summary>
    /// UdpConsoleControl.xaml 的交互逻辑
    /// </summary>
    public partial class UdpConsoleControl : UserControl
    {
        // 使用UdpManager处理UDP通信
        private UdpManager? udpManager;

        // 控制是否显示时间戳
        private bool showTimestamp = true;
        // 当前段落，用于合并无时间戳的消息
        private Paragraph? currentParagraph = null;

        public UdpConsoleControl()
        {
            InitializeComponent();
            // 注册编码提供程序以支持GB2312等编码
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
        }

        private void StartListenButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取用户输入的本地监听端口
                int localPort = int.Parse(LocalPortTextBox.Text);

                // 创建UdpManager实例
                udpManager = new UdpManager(
                    Dispatcher,
                    AppendTextToRecvTextBox,
                    // 添加更新连接状态指示器颜色的回调函数
                    (brush) => { UdpLinkPointer.Fill = brush; }
                );

                // 尝试初始化UDP客户端并开始监听
                bool isInitialized = udpManager.Initialize(localPort);

                if (isInitialized)
                {
                    // 初始化成功
                    AppendTextToRecvTextBox($"成功在端口 {localPort} 上开始监听", "监听");
                    StartListenButton.IsEnabled = false;
                    StopListenButton.IsEnabled = true;
                    LocalPortTextBox.IsEnabled = false;
                }
                else
                {
                    AppendTextToRecvTextBox($"初始化监听失败", "错误");
                }
            }
            catch (Exception ex)
            {
                // 显示错误信息
                AppendTextToRecvTextBox($"开始监听错误：{ex.Message}", "错误");
                MessageBox.Show($"开始监听失败：{ex.Message}");
            }
        }

        private void StopListenButton_Click(object sender, RoutedEventArgs e)
        {
            // 使用UdpManager停止监听
            if (udpManager != null)
            {
                try
                {
                    udpManager.Close();
                    AppendTextToRecvTextBox($"已停止监听", "监听");
                    StartListenButton.IsEnabled = true;
                    StopListenButton.IsEnabled = false;
                    LocalPortTextBox.IsEnabled = true;
                }
                catch (Exception ex)
                {
                    AppendTextToRecvTextBox($"停止监听错误：{ex.Message}", "错误");
                }
            }
        }

        private async void SendButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (udpManager == null || !udpManager.IsInitialized())
                {
                    AppendTextToRecvTextBox("请先开始监听再发送消息", "错误");
                    return;
                }

                // 获取要发送的消息
                string message = new TextRange(SendTextBox.Document.ContentStart, SendTextBox.Document.ContentEnd).Text;
                if (string.IsNullOrEmpty(message))
                {
                    AppendTextToRecvTextBox("消息内容不能为空", "错误");
                    return;
                }

                // 根据自动换行复选框状态处理消息
                if (AutoNewLineCheckBox.IsChecked == true)
                {
                    // 如果勾选了自动换行，确保消息末尾有换行符
                    if (!message.EndsWith("\r\n") && !message.EndsWith("\n"))
                    {
                        message += "\r\n";
                    }
                }
                else
                {
                    // 如果未勾选自动换行，移除消息末尾的换行符
                    message = message.TrimEnd('\r', '\n');
                }

                // 获取编码格式
                string encodingName = (EncodingComboBox.SelectedItem as ComboBoxItem)?.Content.ToString() ?? "UTF-8";
                Encoding encoding = GetEncodingByName(encodingName);

                bool sendResult = false;
                string sendType = "发>> ";

                // 根据选择的发送类型发送消息
                if (UnicastRadioButton.IsChecked == true)
                {
                    // 单播
                    string remoteIP = RemoteIpTextBox.Text;
                    int remotePort = int.Parse(RemotePortTextBox.Text);
                    sendResult = await udpManager.SendUnicastMessageAsync(message, remoteIP, remotePort);
                    sendType = $"发>> [{remoteIP}:{remotePort}]";
                }
                else if (MulticastRadioButton.IsChecked == true)
                {
                    // 组播
                    string multicastIP = MulticastIpTextBox.Text;
                    int multicastPort = int.Parse(MulticastPortTextBox.Text);
                    
                    // 确保已加入组播组
                    if (!udpManager.JoinMulticastGroup(multicastIP))
                    {
                        return;
                    }
                    
                    sendResult = await udpManager.SendMulticastMessageAsync(message, multicastIP, multicastPort);
                    sendType = $"组播>> [{multicastIP}:{multicastPort}]";
                }
                else if (BroadcastRadioButton.IsChecked == true)
                {
                    // 广播
                    int broadcastPort = int.Parse(RemotePortTextBox.Text);
                    sendResult = await udpManager.SendBroadcastMessageAsync(message, broadcastPort);
                    sendType = $"广播>> [255.255.255.255:{broadcastPort}]";
                }

                // 显示发送结果
                if (sendResult)
                {
                    AppendTextToRecvTextBox($"{message}", sendType);
                    // 保留发送框内容，不自动清空
                }
                else
                {
                    AppendTextToRecvTextBox($"发送失败", "错误");
                }
            }
            catch (Exception ex)
            {
                AppendTextToRecvTextBox($"发送消息错误：{ex.Message}", "错误");
                MessageBox.Show($"发送失败：{ex.Message}");
            }
        }

        // 根据名称获取编码格式
        private Encoding GetEncodingByName(string encodingName)
        {
            switch (encodingName)
            {
                case "ASCII":
                    return Encoding.ASCII;
                case "GB2312":
                    return Encoding.GetEncoding("GB2312");
                case "GBK":
                    return Encoding.GetEncoding("GBK");
                case "Unicode":
                    return Encoding.Unicode;
                case "UTF-8":
                default:
                    return Encoding.UTF8;
            }
        }

        // 在UI线程上更新RichTextBox - 支持添加时间戳和消息类型，以及根据消息类型设置不同颜色
        private void AppendTextToRecvTextBox(string text, string messageType = "")
        {
            if (Dispatcher.CheckAccess())
            {
                // 为不同类型的消息设置不同的颜色
                SolidColorBrush textBrush = Brushes.Black; // 默认黑色
                if (messageType.StartsWith("发>> ") || messageType.StartsWith("组播>> ") || messageType.StartsWith("广播>> "))
                {
                    textBrush = new SolidColorBrush(Color.FromRgb(0, 120, 215)); // 好看的蓝色
                }
                else if (messageType == "错误")
                {
                    textBrush = Brushes.Red; // 错误消息为红色
                }
                else if (messageType == "监听" || messageType == "连接" || messageType == "断开")
                {
                    textBrush = Brushes.Green; // 监听相关消息为绿色
                }

                if (showTimestamp)
                {
                    // 选中时间戳模式：为每条消息创建新段落，自动换行
                    Paragraph paragraph = new() { LineHeight = 1.05 }; // 设置更紧凑的行高
                    RecvTextBox.Document.Blocks.Add(paragraph);

                    // 添加时间戳和消息类型（灰色）
                    if (!string.IsNullOrEmpty(messageType))
                    {
                        string timestamp = DateTime.Now.ToString("HH:mm:ss.fff");
                        Run timestampRun = new($"[{timestamp}]{messageType}");
                        timestampRun.Foreground = Brushes.Gray;
                        paragraph.Inlines.Add(timestampRun);
                    }

                    // 添加消息内容
                    Run textRun = new(text);
                    textRun.Foreground = textBrush;
                    paragraph.Inlines.Add(textRun);
                }
                else
                {
                    // 未选中时间戳模式：合并到当前段落，不自动换行
                    if (currentParagraph == null)
                    {
                        currentParagraph = new Paragraph() { LineHeight = 1.05 };
                        RecvTextBox.Document.Blocks.Add(currentParagraph);
                    }

                    // 添加消息内容，不添加时间戳
                    Run textRun = new(text);
                    textRun.Foreground = textBrush;
                    currentParagraph.Inlines.Add(textRun);
                }

                // 确保RichTextBox自动滚动到底部
                RecvTextBox.ScrollToEnd();
            }
            else
            {
                // 在非UI线程上，使用Dispatcher调用此方法
                Dispatcher.Invoke(() => AppendTextToRecvTextBox(text, messageType));
            }
        }

        // 清除接收文本框内容
        private void ClearRecvButton_Click(object sender, RoutedEventArgs e)
        {
            RecvTextBox.Document.Blocks.Clear();
        }

        // 复制接收文本框内容
        private void CopyRecvButton_Click(object sender, RoutedEventArgs e)
        {
            string text = new TextRange(RecvTextBox.Document.ContentStart, RecvTextBox.Document.ContentEnd).Text;
            if (!string.IsNullOrEmpty(text))
            {
                Clipboard.SetText(text);
            }
        }

        // 粘贴到发送文本框
        private void PasteSendButton_Click(object sender, RoutedEventArgs e)
        {
            if (Clipboard.ContainsText())
            {
                string text = Clipboard.GetText();
                SendTextBox.Document.Blocks.Clear();
                SendTextBox.Document.Blocks.Add(new Paragraph(new Run(text)));
            }
        }

        // 清除发送文本框内容
        private void ClearSendButton_Click(object sender, RoutedEventArgs e)
        {
            SendTextBox.Document.Blocks.Clear();
        }

        // 时间戳复选框选中事件
        private void TimestampCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            showTimestamp = true;
            // 切换到时间戳模式时，创建新的段落
            currentParagraph = null;
        }

        // 时间戳复选框取消选中事件
        private void TimestampCheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            showTimestamp = false;
            // 切换到无时间戳模式时，初始化当前段落
            if (currentParagraph == null)
            {
                currentParagraph = new Paragraph() { LineHeight = 1.05 };
                RecvTextBox.Document.Blocks.Add(currentParagraph);
            }
        }
    }
}